#!/usr/bin/env python3
"""
数学运算模块
提供类型安全的数学运算功能，包含完善的错误处理和日志记录
"""

import logging
import math
from typing import Union, Optional, Any
from dataclasses import dataclass
from enum import Enum

# 配置日志
logger = logging.getLogger(__name__)

class ErrorCode(Enum):
    """错误代码枚举"""
    DIVISION_BY_ZERO = "DIVISION_BY_ZERO"
    NEGATIVE_SQUARE_ROOT = "NEGATIVE_SQUARE_ROOT"
    INVALID_EXPRESSION = "INVALID_EXPRESSION"
    TYPE_ERROR = "TYPE_ERROR"
    OVERFLOW_ERROR = "OVERFLOW_ERROR"
    VALUE_ERROR = "VALUE_ERROR"

@dataclass
class CalculationResult:
    """计算结果数据类"""
    success: bool
    result: Union[float, str]
    error_code: Optional[ErrorCode] = None
    error_message: Optional[str] = None

class MathOperations:
    """数学运算类，提供类型安全的数学计算功能"""
    
    @staticmethod
    def validate_number(value: Any, param_name: str = "number") -> float:
        """验证并转换数字输入
        
        Args:
            value: 要验证的值
            param_name: 参数名称，用于错误信息
            
        Returns:
            转换后的浮点数
            
        Raises:
            ValueError: 当输入不是有效数字时
        """
        try:
            if isinstance(value, (int, float)):
                result = float(value)
                if math.isnan(result) or math.isinf(result):
                    raise ValueError(f"{param_name} 不能是 NaN 或无穷大")
                return result
            elif isinstance(value, str):
                result = float(value)
                if math.isnan(result) or math.isinf(result):
                    raise ValueError(f"{param_name} 不能是 NaN 或无穷大")
                return result
            else:
                raise ValueError(f"{param_name} 必须是数字类型，得到 {type(value).__name__}")
        except (ValueError, TypeError) as e:
            logger.error(f"数字验证失败: {param_name}={value}, 错误: {e}")
            raise ValueError(f"无效的 {param_name}: {value}")
    
    @classmethod
    def add(cls, a: Any, b: Any) -> CalculationResult:
        """安全的加法运算"""
        try:
            num_a = cls.validate_number(a, "a")
            num_b = cls.validate_number(b, "b")
            result = num_a + num_b
            
            logger.info(f"加法运算: {num_a} + {num_b} = {result}")
            return CalculationResult(success=True, result=result)
            
        except ValueError as e:
            logger.error(f"加法运算失败: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：{str(e)}",
                error_code=ErrorCode.TYPE_ERROR,
                error_message=str(e)
            )
        except OverflowError as e:
            logger.error(f"加法运算溢出: {e}")
            return CalculationResult(
                success=False,
                result="错误：数值溢出",
                error_code=ErrorCode.OVERFLOW_ERROR,
                error_message=str(e)
            )
    
    @classmethod
    def subtract(cls, a: Any, b: Any) -> CalculationResult:
        """安全的减法运算"""
        try:
            num_a = cls.validate_number(a, "a")
            num_b = cls.validate_number(b, "b")
            result = num_a - num_b
            
            logger.info(f"减法运算: {num_a} - {num_b} = {result}")
            return CalculationResult(success=True, result=result)
            
        except ValueError as e:
            logger.error(f"减法运算失败: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：{str(e)}",
                error_code=ErrorCode.TYPE_ERROR,
                error_message=str(e)
            )
    
    @classmethod
    def multiply(cls, a: Any, b: Any) -> CalculationResult:
        """安全的乘法运算"""
        try:
            num_a = cls.validate_number(a, "a")
            num_b = cls.validate_number(b, "b")
            result = num_a * num_b
            
            logger.info(f"乘法运算: {num_a} * {num_b} = {result}")
            return CalculationResult(success=True, result=result)
            
        except ValueError as e:
            logger.error(f"乘法运算失败: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：{str(e)}",
                error_code=ErrorCode.TYPE_ERROR,
                error_message=str(e)
            )
        except OverflowError as e:
            logger.error(f"乘法运算溢出: {e}")
            return CalculationResult(
                success=False,
                result="错误：数值溢出",
                error_code=ErrorCode.OVERFLOW_ERROR,
                error_message=str(e)
            )
    
    @classmethod
    def divide(cls, a: Any, b: Any) -> CalculationResult:
        """安全的除法运算"""
        try:
            num_a = cls.validate_number(a, "a")
            num_b = cls.validate_number(b, "b")
            
            if num_b == 0:
                logger.warning(f"除零错误: {num_a} / {num_b}")
                return CalculationResult(
                    success=False,
                    result="错误：除数不能为零",
                    error_code=ErrorCode.DIVISION_BY_ZERO,
                    error_message="Division by zero"
                )
            
            result = num_a / num_b
            logger.info(f"除法运算: {num_a} / {num_b} = {result}")
            return CalculationResult(success=True, result=result)
            
        except ValueError as e:
            logger.error(f"除法运算失败: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：{str(e)}",
                error_code=ErrorCode.TYPE_ERROR,
                error_message=str(e)
            )
    
    @classmethod
    def power(cls, base: Any, exponent: Any) -> CalculationResult:
        """安全的乘方运算"""
        try:
            num_base = cls.validate_number(base, "base")
            num_exponent = cls.validate_number(exponent, "exponent")
            
            # 检查可能的溢出情况
            if abs(num_base) > 1000 and abs(num_exponent) > 100:
                logger.warning(f"乘方运算可能溢出: {num_base} ** {num_exponent}")
                return CalculationResult(
                    success=False,
                    result="错误：乘方运算可能导致数值溢出",
                    error_code=ErrorCode.OVERFLOW_ERROR,
                    error_message="Power operation may cause overflow"
                )
            
            result = num_base ** num_exponent
            logger.info(f"乘方运算: {num_base} ** {num_exponent} = {result}")
            return CalculationResult(success=True, result=result)
            
        except ValueError as e:
            logger.error(f"乘方运算失败: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：{str(e)}",
                error_code=ErrorCode.TYPE_ERROR,
                error_message=str(e)
            )
        except OverflowError as e:
            logger.error(f"乘方运算溢出: {e}")
            return CalculationResult(
                success=False,
                result="错误：数值溢出",
                error_code=ErrorCode.OVERFLOW_ERROR,
                error_message=str(e)
            )
    
    @classmethod
    def square_root(cls, number: Any) -> CalculationResult:
        """安全的平方根运算"""
        try:
            num = cls.validate_number(number, "number")
            
            if num < 0:
                logger.warning(f"负数平方根错误: sqrt({num})")
                return CalculationResult(
                    success=False,
                    result="错误：不能计算负数的平方根",
                    error_code=ErrorCode.NEGATIVE_SQUARE_ROOT,
                    error_message="Cannot calculate square root of negative number"
                )
            
            result = math.sqrt(num)
            logger.info(f"平方根运算: sqrt({num}) = {result}")
            return CalculationResult(success=True, result=result)
            
        except ValueError as e:
            logger.error(f"平方根运算失败: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：{str(e)}",
                error_code=ErrorCode.TYPE_ERROR,
                error_message=str(e)
            )
    
    @classmethod
    def calculate_expression(cls, expression: str, max_length: int = 1000) -> CalculationResult:
        """安全的表达式计算
        
        Args:
            expression: 要计算的数学表达式
            max_length: 表达式最大长度限制
        """
        try:
            if not isinstance(expression, str):
                raise ValueError("表达式必须是字符串类型")
            
            if len(expression) > max_length:
                logger.warning(f"表达式过长: {len(expression)} > {max_length}")
                return CalculationResult(
                    success=False,
                    result=f"错误：表达式长度超过限制 ({max_length} 字符)",
                    error_code=ErrorCode.VALUE_ERROR,
                    error_message="Expression too long"
                )
            
            # 安全的表达式验证
            allowed_chars = set('0123456789+-*/().** ')
            if not all(c in allowed_chars for c in expression):
                logger.warning(f"表达式包含非法字符: {expression}")
                return CalculationResult(
                    success=False,
                    result="错误：表达式包含非法字符",
                    error_code=ErrorCode.INVALID_EXPRESSION,
                    error_message="Expression contains invalid characters"
                )
            
            # 使用 eval 进行计算（在受控环境中）
            result = eval(expression, {"__builtins__": {}}, {})
            
            if math.isnan(result) or math.isinf(result):
                logger.warning(f"表达式计算结果无效: {expression} = {result}")
                return CalculationResult(
                    success=False,
                    result="错误：计算结果无效",
                    error_code=ErrorCode.VALUE_ERROR,
                    error_message="Invalid calculation result"
                )
            
            logger.info(f"表达式计算: {expression} = {result}")
            return CalculationResult(success=True, result=float(result))
            
        except ZeroDivisionError:
            logger.warning(f"表达式除零错误: {expression}")
            return CalculationResult(
                success=False,
                result="错误：除数不能为零",
                error_code=ErrorCode.DIVISION_BY_ZERO,
                error_message="Division by zero in expression"
            )
        except (SyntaxError, ValueError, TypeError) as e:
            logger.error(f"表达式语法错误: {expression}, 错误: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：无效的数学表达式 - {str(e)}",
                error_code=ErrorCode.INVALID_EXPRESSION,
                error_message=str(e)
            )
        except Exception as e:
            logger.error(f"表达式计算未知错误: {expression}, 错误: {e}")
            return CalculationResult(
                success=False,
                result=f"错误：计算失败 - {str(e)}",
                error_code=ErrorCode.VALUE_ERROR,
                error_message=str(e)
            )